/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package jwu2.core;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.List;
import jwu2.indexserver.Packet;
import jwu2.addondb.AddonDBEntry;
import jwu2.log.Logger;

/**
 *
 * @author Rolf
 */
public class IndexServerCommunication {
    
    private final String serverAddress = "localhost";
    private static IndexServerCommunication singleton;
    
    private Socket socket;
    private ObjectInputStream in;
    private ObjectOutputStream out;
    
    private IndexServerCommunication() {
    }
    
    public synchronized static IndexServerCommunication singleton() {
        if( singleton == null ) {
            singleton = new IndexServerCommunication();
        }
        
        return singleton;
    }
    
    private synchronized boolean connectToIndexServer() {
        if( socket == null || !socket.isConnected() ) {
            try {
                socket = new Socket();
                socket.setSoTimeout(1000);
                SocketAddress server = new InetSocketAddress(serverAddress, 4260);
                
                socket.connect(server);
                
                out = new ObjectOutputStream( socket.getOutputStream() );
                in = new ObjectInputStream( socket.getInputStream() );
                
            } catch (Exception e) {
                Logger.logln("Exception opening connection to IndexServer: "+e);
                return false;
            }
        }
        
        return true;
                
    }

    private void disconnectFromIndexServer() {
        sendPacket(new Packet(Packet.NetProtocol.BYE));
    }

    private Packet receivePacket() {
        try {
            Packet p = (Packet) in.readObject();
            
            Logger.logln("Received packet ["+p.getCommand()+"]");
            
            return p;
        }
        catch(Exception e) {
            Logger.logln("Error receiving packet: "+e);
        }
        
        return null;
    }
    
    private void sendPacket(Packet p) {
        try {
            out.writeObject(p);
            out.flush();
            
            Logger.logln("Sent packet ["+p.getCommand()+"]");
        }
        catch(Exception e) {
            Logger.logln("Error sending packet: "+e);
        }
    }
    
    public List<AddonDBEntry> getUpdatedAddonsSinceTimestamp(long timestamp) {
        List<AddonDBEntry> updatedAddons = new ArrayList<AddonDBEntry>();
        
        if( connectToIndexServer() ) {
        
            Packet whatsNewPacket = new Packet(Packet.NetProtocol.WHATSNEW);

            whatsNewPacket.addData(timestamp);

            sendPacket(whatsNewPacket);

            Packet reply = receivePacket();

            Logger.logln("Retrieved "+reply.getData().size()+" new/updated addons from IndexServer");

            for(Object o : reply.getData()) {
                updatedAddons.add((AddonDBEntry) o);
            }

            disconnectFromIndexServer();
        }
        
        return updatedAddons;
    }
}
